在網頁開發中,某些操作會花費較長時間才能完成,例如:
這些操作若同步執行,將會造成瀏覽器被阻塞(卡住),直到操作完成。為了避免這種情況,JavaScript 引入了非同步操作,讓程式碼在等待這些操作的同時,能夠繼續執行其他工作。
# Callback 函數
非同步操作的傳統解決方案是使用 Callback(回調函數),即將一個函數作為參數傳入,並在非同步操作完成後執行該函數。
範例:
function fetchData(callback) {
setTimeout(() => {
const data = "從伺服器獲取的資料";
callback(data);
}, 2000); // 模擬兩秒的延遲
}
fetchData((data) => {
console.log(data); // 兩秒後印出資料
});
在這個範例中,fetchData() 使用 setTimeout() 模擬一個非同步操作,兩秒後調用傳入的 callback 函數,並傳遞獲取到的資料。
# Promise:現代的非同步解決方案
為了解決回調地獄(Callback Hell)這種不斷嵌套回調函數導致的代碼難以維護的問題,JavaScript 提供了 Promise,這是一種用來處理非同步操作的物件,允許你以更直觀的方式撰寫非同步代碼。
Promise 的三種狀態:
範例:使用 Promise 處理非同步操作
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = true; // 模擬操作成功或失敗
if (success) {
resolve("資料獲取成功");
} else {
reject("資料獲取失敗");
}
}, 2000);
});
}
fetchData()
.then((data) => {
console.log(data); // 兩秒後印出 "資料獲取成功"
})
.catch((error) => {
console.log(error); // 若失敗,印出錯誤訊息
});
在這個範例中,fetchData() 函數回傳一個 Promise。在 *then() *方法中,我們可以處理成功的結果;在 catch() 方法中,我們可以處理失敗的情況。
Async/Await:更簡潔的語法
Async/Await 是 ES2017 中引入的一個語法,能夠更直觀地撰寫非同步代碼,避免過多的 then() 和 catch()。
範例:使用 Async/Await
async function fetchData() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("資料已經成功獲取");
}, 2000);
});
}
async function getData() {
const data = await fetchData();
console.log(data); // 兩秒後印出 "資料已經成功獲取"
}
getData();
在這段代碼中,我們使用 async 來聲明 getData() 是一個非同步函數,並使用 await 來等待 fetchData() 的結果。這使得程式碼看起來像是同步的,但實際上仍然是非同步執行的。
實際應用:處理 API 請求
在現實應用中,Promise 和 Async/Await 經常用來處理 API 請求。例如,可以使用 fetch() 函數來發送 HTTP 請求,並搭配 Promise 來處理結果。
範例:使用 fetch() 處理 API 請求
async function getUserData() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users/1');
const data = await response.json();
console.log(data);
} catch (error) {
console.log("錯誤:", error);
}
}
getUserData();
這段代碼會從一個測試 API 中獲取使用者數據,並使用 await 來等待 fetch() 函數的結果。如果請求成功,資料會被印出;如果請求失敗,錯誤會被捕捉並印出。
今天,我學習了 JavaScript 中的非同步操作,並探討了三種常見的方式來處理非同步邏輯:回調函數、Promise,以及更現代的 Async/Await 語法。這些技術對於處理動態資料、實現網頁互動,以及建立高效的使用者體驗至關重要。
明天,將繼續探討 JavaScript 的更多應用,包括如何使用外部資料進行更加複雜的網頁應用開發。